package client;

import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import org.omg.CORBA_2_3.portable.OutputStream;

import event.Event;
import event.EventHandler;

public class PeerFileRequestEventHandler implements EventHandler {

	public static final int BUFFER_SIZE = 4096;

	@Override
	public void handle(Event e) {
		if (e.type == Event.FIL_TYPE) {
			File file = new File(e.parameters);

			long offset = e.packageOffset;

			DataOutputStream os = e.getOutputStream();

			if (os != null) {
				if (file.isFile()) {
					try {
						sendFile(file, "", offset, os);
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				} else if (file.isDirectory()) {
					recurseFiles(file, "", offset, os);
				}

				try {
					os.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		}
	}

	private void sendFile(File file, String path, long offset,
			DataOutputStream os) throws IOException {
		FileInputStream fis = new FileInputStream(file);
		BufferedInputStream bif = new BufferedInputStream(fis);

		/*
		 * Send in chunks.
		 */

		System.out.println("Sending file: " + file.getName());
		System.out.println("File size: " + file.length());
		System.out.println("Segment max size: " + BUFFER_SIZE);

		int count = 0;

		if (offset > 0) {
			bif.skip(offset);
		}

		long len = file.length();
		int segmentLen;
		while (offset < len) {
			segmentLen = (int) ((len - offset) < BUFFER_SIZE ? (len - offset)
					: BUFFER_SIZE);
			byte[] buffer = new byte[segmentLen];

			// ------------------------------------------
			// This is the protocol for every message:
			// ------------------------------------------
			// (int) EVENT_TYPE
			// (long) OFFSET (offset of segment in TOTAL_LENGTH)
			// (long) TOTAL_LENGTH (total message length)
			// (int) SEGMENT_LENGTH (<= TOTAL_LENGTH)
			// (UTF) PARAMETER
			// (byte[]) BUFFER (of size SEGMENT_LENGTH)
			// ------------------------------------------

			os.writeInt(Event.FIL_TYPE);
			os.writeLong(offset);
			os.writeLong(len);
			os.writeInt(segmentLen);
			os.writeUTF(file.getAbsolutePath() + "DELIMETER" + path + "/"
					+ file.getName()); // Use the delimeter ' '

			offset += bif.read(buffer, 0, segmentLen);

			os.write(buffer);
			os.flush();

			++count;
		}

		System.out.println("Bytes read: " + offset);
		System.out.println("Number of segments: " + count);
	}

	private void recurseFiles(File file, String path, long offset,
			DataOutputStream os) {
		if (file.isDirectory()) {
			int index = file.getPath().lastIndexOf('/');
			path += file.getPath().substring(index);

			File[] files = file.listFiles(CustomFileFilter.getInstance());
			for (File f : files) {
				recurseFiles(f, path, offset, os);
			}
		} else if (file.isFile()) {
			try {
				sendFile(file, path, offset, os);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
